package meiyunting.shiwuzhaoling.service.impl;

import meiyunting.shiwuzhaoling.dto.ItemDTO;
import meiyunting.shiwuzhaoling.model.Item;
import meiyunting.shiwuzhaoling.model.ItemStatus;
import meiyunting.shiwuzhaoling.model.ItemType;
import meiyunting.shiwuzhaoling.model.User;
import meiyunting.shiwuzhaoling.repository.ClaimRepository;
import meiyunting.shiwuzhaoling.repository.ItemRepository;
import meiyunting.shiwuzhaoling.service.ItemService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
import java.util.UUID;

/**
 * 物品信息服务实现类
 */
@Service
public class ItemServiceImpl implements ItemService {

    private final ItemRepository itemRepository;
    private final ClaimRepository claimRepository;
    
    @Value("${file.upload-dir}")
    private String uploadDir;

    public ItemServiceImpl(ItemRepository itemRepository, ClaimRepository claimRepository) {
        this.itemRepository = itemRepository;
        this.claimRepository = claimRepository;
    }

    @Override
    public Item createItem(ItemDTO itemDTO, MultipartFile image, User user) {
        Item newItem = new Item();
        newItem.setUser(user);
        newItem.setStatus(itemDTO.getStatus());
        newItem.setType(itemDTO.getType());
        newItem.setTitle(itemDTO.getTitle());
        newItem.setDescription(itemDTO.getDescription());
        newItem.setContactInfo(itemDTO.getContactInfo());
        newItem.setLostTime(itemDTO.getLostTime());
        
        if (image != null && !image.isEmpty()) {
            String imagePath = saveImage(image);
            newItem.setImagePath(imagePath);
        }
        
        return itemRepository.save(newItem);
    }

    @Override
    public List<Item> getAllItems() {
        return itemRepository.findAll();
    }

    @Override
    public Optional<Item> getItemById(Long id) {
        return itemRepository.findById(id);
    }

    @Override
    public Item findItemById(Long id) {
        return itemRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("物品不存在，ID: " + id));
    }

    @Override
    public List<Item> getItemsByStatus(ItemStatus status) {
        return itemRepository.findByStatus(status);
    }

    @Override
    public List<Item> getItemsByType(ItemType type) {
        return itemRepository.findByType(type);
    }

    @Override
    public List<Item> getItemsByStatusAndType(ItemStatus status, ItemType type) {
        return itemRepository.findByStatusAndType(status, type);
    }

    @Override
    public List<Item> searchItems(String keyword) {
        return itemRepository.findByTitleContainingOrDescriptionContaining(keyword, keyword);
    }

    @Override
    public Item updateItem(Long id, ItemDTO itemDTO, MultipartFile image, User user) {
        Optional<Item> optionalItem = itemRepository.findById(id);
        if (optionalItem.isPresent()) {
            Item existingItem = optionalItem.get();
            
            // 验证是否是物品的发布者
            if (!existingItem.getUser().getId().equals(user.getId())) {
                throw new RuntimeException("您没有权限修改此物品信息");
            }
            
            existingItem.setStatus(itemDTO.getStatus());
            existingItem.setType(itemDTO.getType());
            existingItem.setTitle(itemDTO.getTitle());
            existingItem.setDescription(itemDTO.getDescription());
            existingItem.setContactInfo(itemDTO.getContactInfo());
            existingItem.setLostTime(itemDTO.getLostTime());
            
            if (image != null && !image.isEmpty()) {
                String imagePath = saveImage(image);
                existingItem.setImagePath(imagePath);
            }
            
            return itemRepository.save(existingItem);
        }
        return null;
    }

    @Override
    @Transactional
    public void deleteItem(Long id, User user) {
        Optional<Item> optionalItem = itemRepository.findById(id);
        if (optionalItem.isPresent()) {
            Item item = optionalItem.get();
            
            // 验证是否是物品的发布者
            if (!item.getUser().getId().equals(user.getId())) {
                throw new RuntimeException("您没有权限删除此物品信息");
            }
            
            // 先删除与物品关联的所有认领记录
            claimRepository.findByItem(item).forEach(claim -> {
                claimRepository.delete(claim);
            });
            
            // 然后删除物品
            itemRepository.deleteById(id);
        }
    }

    @Override
    public List<Item> getItemsByUser(User user) {
        return itemRepository.findByUser(user);
    }

    @Override
    public Item claimItem(Long id, User user) {
        Optional<Item> optionalItem = itemRepository.findById(id);
        if (optionalItem.isPresent()) {
            Item item = optionalItem.get();
            
            // 验证物品是否已被认领
            if (item.getClaimedBy() != null) {
                throw new RuntimeException("此物品已被认领");
            }
            
            // 设置认领信息
            item.setClaimedBy(user);
            item.setClaimedAt(LocalDateTime.now());
            
            return itemRepository.save(item);
        }
        throw new RuntimeException("物品不存在");
    }
    
    /**
     * 保存图片并返回路径
     */
    private String saveImage(MultipartFile image) {
        try {
            // 创建上传目录
            File uploadDirectory = new File(uploadDir);
            if (!uploadDirectory.exists()) {
                uploadDirectory.mkdirs();
            }
            
            // 生成唯一的文件名
            String originalFilename = image.getOriginalFilename();
            String extension = originalFilename.substring(originalFilename.lastIndexOf("."));
            String filename = UUID.randomUUID().toString() + "_" + originalFilename;
            
            // 保存文件
            Path targetPath = Paths.get(uploadDir).resolve(filename);
            Files.copy(image.getInputStream(), targetPath, StandardCopyOption.REPLACE_EXISTING);
            
            // 返回相对路径
            return "/uploads/images/" + filename;
        } catch (IOException e) {
            throw new RuntimeException("无法保存图片: " + e.getMessage());
        }
    }
} 